[Este documento viene del tema anterior Binomial 1.]
El problema con este programa, otra vez, es la repetición. Los tres bucles que calculan el factorial son el mismo exactamente. Simplemente se ha cambiado n por k y luego por m. Aquí es donde hay que hacer una función. Esencialmente, cada bucle recibe un número y produce otro (en el primero se usa n como entrada y se produce n_fact como salida). Eso sugiere hacer una función que reciba un entero y devuelva otro. La función tendrá la siguiente cabecera:
int factorial(int n) { // aquí viene el cuerpo: las instrucciones de la función }
La cabecera es la primera línea, donde sale el tipo de retorno, el nombre y los parámetros. El tipo de retorno es int porque esta función devolverá un entero como resultado. El nombre es factorial que describe bien lo que hace la función. Finalmente los datos de entrada, lo que se necesita para calcular un factorial, es un entero también, que hemos puesto entre paréntesis y con su tipo, tal como una declaración de variables sin punto y coma.
Ahora hay que implementar la función, es decir hay que rellenar su cuerpo con las instrucciones necesarias para calcular el factorial. El cuerpo de la función se debe implementar con las dos condiciones siguientes:
Sabido esto, la implementación es la siguiente:
int factorial(int n) { int fact = 1; while (n > 0) { fact = fact * n; n = n - 1; } return fact; }
El programa tiene una variable local, llamada fact que sirve para hacer el cálculo, y que tiene una vida paralela a la ejecución de la función factorial. Es decir, fact se crea al principio de ejecutar factorial pero cuando el programa devuelve el resultado y la función factorial acaba su ejecución, la variable fact desaparece.
La instrucción return devuelve el resultado, que quiere decir que el valor resultante se utilizará allí donde era requerido. Esto se verá mejor rehaciendo el programa principal para utilizar la función:
int main() { int n, k, m; int n_fact = 1, k_fact = 1, m_fact = 1; cout << "Entra n i k: "; cin >> n >> k; m = n - k; n_fact = factorial(n); k_fact = factorial(k); m_fact = factorial(m); cout << n_fact / (k_fact * m_fact) << endl; }
Allí donde antes había los whiles, ahora hay las llamadas a la función factorial. Allí donde nos interese tener el valor resultante, escribiremos la llamada. O sea, hacer:
n_fact = factorial(n);
implica llamar a la función, obtener el resultado, y luego asignarlo a la variable n_fact. Se puede sustituir mentalmente la expresión factorial(n) por el resultado obtenido al haber concluido su ejecución. Si n vale 4, por ejemplo, factorial(n) valdrá 24 y por tanto la instrucción anterior es como haber hecho:
n_fact = 24;
De hecho, con la función las variables n_fact, k_fact y m_fact no sirven para nada, porque el resultado de las llamadas a la función fact se pueden poner directamente al final:
cout << factorial(n) / (factorial(k) * factorial(m)) << endl;
Incluso la variable m no sirve mucho ahora, podemos cambiar factorial(m) por factorial(n - k) y prescindir de m:
cout << factorial(n) / (factorial(k) * factorial(n - k)) << endl;
El programa final, contando que está definida la función factorial previamente, es este:
int main() { int n, k; cout << "Entra n i k: "; cin >> n >> k; cout << factorial(n) / (factorial(k) * factorial(n - k)) << endl; }
La existencia de la función factorial ha reducido el programa increíblemente, hasta el punto de pasar de más de 20 instrucciones a solamente 4. Aparte la función factorial ha quedado aislada y permite analizar el programa por separado, sin necesitar entenderlo todo a la vez.
En preparación